package com.airshare;

import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.Hashtable;


import javax.jmdns.ServiceInfo;
import javax.swing.DefaultListModel;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.ListSelectionModel;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;


// A simple UI for Airshare.
public class UI extends JFrame implements ActionListener, ItemListener, FSConstants {
	
	private Main app;
	private String userName;
	private ShareDir shareDirectory;
	
	private JSplitPane vsp; // vertical split -> separates foreign user file list and self file list
	private JSplitPane hsp; // Horiz split -> separates user list from the rest of the UI
	private Container container;
		
	private Hashtable<String, FileClient> clients = new Hashtable<String, FileClient>();
	private UserListPanel userListPanel;
	private FilePanel fp;
	
	public UI(String user, ShareDir shareDir, Main app) {
		this.shareDirectory = shareDir;
		this.userName = user;
		this.app = app;
		initUI();
	}

	public void initUI() {

		container = this.getContentPane();
		container.setLayout(new BorderLayout());
		
		userListPanel = new UserListPanel();
		fp = new FilePanel();
		hsp = new JSplitPane();
		hsp.setLeftComponent(userListPanel);
		hsp.setRightComponent(fp);
		this.add(hsp);
		
		this.addWindowListener(new WindowAdapter() {
			public void windowClosing(WindowEvent arg0) {
				app.stop();
			}
		});
		
		this.setSize(700,800);
		this.setVisible(true);
	}

	public void showFiles(String userName){
		fp.displayUserFiles(userName);
	}
	
	public void addService(ServiceInfo s) {		
		if(s.getName() != this.userName) {
			FileClient fc = new FileClient(userName,shareDirectory, s.getInetAddresses()[0], s.getPort());
			fc.connect();
			if (fc.isConnected()) {
				clients.put(s.getName(), fc);
			}
		}
		userListPanel.addUser(s.getName());
	}

	public void removeService(ServiceInfo s){
		
		// Get the service Info
		if (clients.containsKey(s.getName())) {
			clients.get(s.getName()).disconnect();
			clients.remove(s.getName());
		}
		userListPanel.removeUser(s.getName());
	}
	
	@Override
	public void actionPerformed(ActionEvent evt) {		
	}

	@Override
	public void itemStateChanged(ItemEvent evt) {
	}
	
    private void centerScreen()
    {
    	Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
    	int x = (int) ((d.getWidth() - getWidth()) / 2);
    	int y = (int) ((d.getHeight() - getHeight()) / 2);
    	setLocation(x, y);
    }
  
    private class UserListPanel extends JPanel {
    	private DefaultListModel listModel;
    	private JList userList;
    	private JScrollPane listPane;
    	
    	public UserListPanel() {
    		setLayout(new BorderLayout());
    		
    		userList = new JList();
    		listModel = new DefaultListModel();
    		userList.setModel(listModel);
    		userList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
    		listPane = new JScrollPane(userList);
    		add(listPane, BorderLayout.CENTER);
    		
    		ListSelectionListener sl = new ListSelectionListener() {

				@Override
				public void valueChanged(ListSelectionEvent evt) {
					int idx = 0;
					// Find out which indexes are selected.
					ListSelectionModel lsm = (ListSelectionModel)evt.getSource();
				
		            int minIndex = lsm.getMinSelectionIndex();
		            int maxIndex = lsm.getMaxSelectionIndex();
				
		            for (int i = minIndex; i <= maxIndex; i++) {
		                if (lsm.isSelectedIndex(i)) {
		                	idx = i;
		                	break;
		                }
		            }
		            UI.this.showFiles((String)listModel.elementAt(idx));
				}
    		};
    		
    		userList.getSelectionModel().addListSelectionListener(sl);
    	}
    	
    	public void addUser(String userName){
    		listModel.addElement(userName);
    		userList.revalidate();
    	}
    	
    	public void removeUser(String userName){
         	if(listModel.contains(userName)) {
         		listModel.removeElement(userName);
         		userList.revalidate();
         	}
    	}
    	
    	public void setSelection(int index){
    		userList.setSelectedIndex(index);
    	}
    }
    
    private class FilePanel extends JPanel {
    	private JList fileList;
    	private DefaultListModel listModel;
    	private JScrollPane listPane;
    	private String nowDisplaying = "";
    	
    	public FilePanel() {
    		setLayout(new BorderLayout());
    		fileList = new JList();
    		listModel = new DefaultListModel();
    		fileList.setModel(listModel);
    		fileList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
    		listPane = new JScrollPane(fileList);
    		add(listPane, BorderLayout.CENTER);
    		
    		MouseListener ml = new MouseAdapter() {

				@Override
				public void mouseClicked(MouseEvent e) {
					if (e.getClickCount() == 2) {
						int idx = fileList.locationToIndex(e.getPoint());
						
						if (idx >=0) {
							System.out.println("GET FILE: " + (String)listModel.elementAt(idx));
							getFile((String)listModel.elementAt(idx));
						}
					}
					
				}    			
    		};
    		
    		fileList.addMouseListener(ml);
    	}
 
    	private void getFile(String fileName){
    		if (nowDisplaying.equalsIgnoreCase(UI.this.userName)){
    			return;
    		}
    		
    		FileClient fc = UI.this.clients.get(nowDisplaying);
    		fc.getFile(fileName);
    	}
    	
    	public void displayUserFiles(String userName) {
    		
    		if (nowDisplaying.equalsIgnoreCase(userName)){
    			return;
    		}
    		listModel.clear();
    		
    		String [] index;
    		
    		if (userName.equalsIgnoreCase(UI.this.userName)) {
    			index = UI.this.shareDirectory.getIndex().split("\n");
    		}
    		else {
    			FileClient fc = UI.this.clients.get(userName);
    			String idx = fc.getIndex();
    			index = idx.split("\n");
    		}
    		
    		for(int i=0; i<index.length; ++i) {
    			String fileName = index[i];
    			if (fileName.startsWith("true")) 
    				continue;
    			else if (fileName.startsWith("false")) 
    				fileName = fileName.substring(5);
    			else
    				continue;
    			
    			listModel.addElement(fileName);
    		}
    		fileList.revalidate();
    		nowDisplaying = userName;
    	}
    }
}
